import { Component, Host, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, OnDestroy, ViewChild, ViewContainerRef } from '@angular/core';
import { Router } from '@angular/router';
import { AppComponent } from '../../../../app.component';
import { Subscription } from 'rxjs/Subscription';
import { CompanyOverviewService } from './companyOverview.service';
import { CompanyEsgService } from '../esg/companyEsg.service';
import { CompanyGlobalCompactService } from '../globalCompact/companyGlobalCompact.service';
import { UtilsService } from '../../../../shared/services/utils.service';
import { CompanyService } from '../company.service';
import { CompanyModel } from '../company.model';
import { ResearchService, ResearchType, ResearchState } from '../../research.service';
import { NewsArticleModel } from './models/newsArticle.model';
import { CompanyRiskRatingService } from '../riskRating/companyRiskRating.service';
import { CompanyGovernanceService } from '../governance/companyGovernance.service';
import { AssessmentList } from '../../../../shared/models/assessment.enum';
import { RatingOverviewModel } from './models/ratingOverview.model';
import * as _ from 'lodash';
import { CompanyReportDownloadModel } from '../shared/companyHeader/companyReportDownload/companyReportDownload.model';
import { BaseComponent } from '../../../../shared/components/baseComponent/base.component';
import { CompanyProductInvolvementService } from '../productInvolvement/companyProductInvolvement.service';

/**
 * Company overview main component.
 * Displays:
 * - ESG overall performance
 * - News articles
 * - Controversy qualitative performance
 * - ESG Research type
 * - GC overall assessment
 *
 * Author: Sorin Spiru
 * Date: 13.01.2018
 */
@Component({
    moduleId: module.id,
    templateUrl: 'companyOverview.component.html',
    styleUrls: ['../company.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    providers: [CompanyProductInvolvementService]

})
export class CompanyOverviewComponent extends BaseComponent implements OnInit, OnDestroy {
    private sub: Subscription;
    public formatRank = UtilsService.formatRank;

    public company: CompanyModel;
    public esgResearchTypeText: string;
    public controversyMaxValue: number;
    public controversyMaxSeverity: string;
    public gcOverallAssessment: number;
    public companyNews: NewsArticleModel[];

    public hasResearch = this.researchService.hasResearch;
    public hasResearchInStatus = this.researchService.hasResearchInStatus;
    public researchType: typeof ResearchType = ResearchType;
    public researchState: typeof ResearchState = ResearchState;
    public riskRating;
    public riskRatingAssessment;
    public overallGovernance;
    public governanceAssessment;
    public ratingModels = {};
    public esgResearchState: ResearchState;
    public riskResearchState: ResearchState;
    public hasActiveInvolvedAssessments: boolean;

    @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

    constructor(
        private cdRef: ChangeDetectorRef,        
        private researchService: ResearchService,
        private companyOverviewService: CompanyOverviewService,
        private companyEsgService: CompanyEsgService,
        private companyGlobalCompactService: CompanyGlobalCompactService,
        public companyService: CompanyService,
        private riskRatingService: CompanyRiskRatingService,        
        private governanceService: CompanyGovernanceService,
        private companyProductInvolvementService: CompanyProductInvolvementService,
        private router: Router,
        @Host() private rootComponent: AppComponent
    ) {
        super(cdRef);
    }

    ngOnInit() {
        window.scrollTo(0, 0);    
        //Remove any filters from company subcription
        this.companyService.company = this.companyService.companySubject.asObservable();
        this.sub = this.companyService.company.subscribe(data => {
            this.company = data;

            // GET ESG RISK RATING
            this.riskResearchState = this.company.riskRatingResearchState == ResearchState.ResearchAvailable || this.company.coreRiskResearchState == ResearchState.ResearchAvailable ?
            ResearchState.ResearchAvailable : (this.company.riskRatingResearchState == ResearchState.ResearchInProgress || this.company.coreRiskResearchState == ResearchState.ResearchInProgress ?
                ResearchState.ResearchInProgress : (this.company.riskRatingResearchState == ResearchState.FrameworkNotApplicable || this.company.coreRiskResearchState == ResearchState.FrameworkNotApplicable ?
                    ResearchState.FrameworkNotApplicable : ResearchState.ResearchNotAvailable));
            if (this.company.hasRiskRatingAccountFeature && this.riskResearchState == ResearchState.ResearchAvailable) {                
                this.riskRatingService.company = this.riskRatingService.getCompanyById(this.company.id);
                this.riskRatingService.company.subscribe(riskRating => {
                    this.ratingModels['riskRating'] = this.handleRiskRating(riskRating);
                },
                    () => this.ratingModels['riskRating'] = this.getRatingUnavailableModel('ESG Risk Rating'),
                    () => this.cdRef.markForCheck());

            } else                
                this.ratingModels['riskRating'] = this.getRatingUnavailableModel('ESG Risk Rating');

            // GET ESG OVERALL PERFORMANCE
            this.esgResearchState = this.company.comprehensiveEsgResearchState == ResearchState.ResearchAvailable || this.company.coreEsgResearchState == ResearchState.ResearchAvailable ?
                ResearchState.ResearchAvailable : (this.company.comprehensiveEsgResearchState == ResearchState.ResearchInProgress || this.company.coreEsgResearchState == ResearchState.ResearchInProgress ?
                    ResearchState.ResearchInProgress : (this.company.comprehensiveEsgResearchState == ResearchState.FrameworkNotApplicable || this.company.coreEsgResearchState == ResearchState.FrameworkNotApplicable ?
                        ResearchState.FrameworkNotApplicable : ResearchState.ResearchNotAvailable));
            if (this.company.hasEsgAccountFeature && this.esgResearchState == ResearchState.ResearchAvailable) {
                this.companyEsgService.getEsgOverallPerformanceSummary(this.company.id)
                    .subscribe(esgRating => {
                        this.ratingModels['esgRating'] = this.handleEsgRating(esgRating);
                    },
                        () => { this.ratingModels['esgRating'] = this.getRatingUnavailableModel('ESG Rating'); },
                        () => this.cdRef.markForCheck());
            } else
                this.ratingModels['esgRating'] = this.getRatingUnavailableModel('ESG Rating');

            // GET CONTROVERSY QUALITATIVE PERFORMANCE
            if (this.company.controversyResearchState && this.company.controversyResearchState == ResearchState.ResearchAvailable) {
                this.companyEsgService.getControversyQualitativePerformance(this.company.id)
                    .subscribe(controversies => {
                        this.ratingModels['controversyRating'] = this.handleControversy(controversies);
                    },
                        () => { this.ratingModels['controversyRating'] = this.getRatingUnavailableModel('Controversies'); },
                        () => this.cdRef.markForCheck());
            } else
                this.ratingModels['controversyRating'] = this.getRatingUnavailableModel('Controversies');

            // GET CORPORATE GOVERNANCE
            if (this.company.corporateGovernanceResearchState && this.company.corporateGovernanceResearchState == ResearchState.ResearchAvailable) {
                this.governanceService.getGovernanceOverallPerformance(this.company.id);
                this.governanceService.overallPerformance
                    .subscribe(governance => {
                        this.ratingModels['cgRating'] = this.handleCorporateGovernance(governance);
                    },
                        () => { this.ratingModels['cgRating'] = this.getRatingUnavailableModel('Corporate Governance'); },
                        () => this.cdRef.markForCheck());
            }
            else
                this.ratingModels['cgRating'] = this.getRatingUnavailableModel('Corporate Governance');
            
             // CREATE PI RATING
            if (this.company.sustainableProductsResearchState == ResearchState.ResearchAvailable)
                this.ratingModels['spRating'] = this.getSPRating();
            else
                this.ratingModels['spRating'] = this.getRatingUnavailableModel('Sustainable Products');

            // CREATE PI RATING
            if (this.company.productInvolvementResearchState == ResearchState.ResearchAvailable)
                this.ratingModels['piRating'] = this.getPIRating();
            else
                this.ratingModels['piRating'] = this.getRatingUnavailableModel('Product Involvement');

            // GET GC OVERALL ASSESSMENT
            if (this.company.gccsResearchState == ResearchState.ResearchAvailable) {
                this.companyGlobalCompactService.getByCompany(this.company.id)
                    .subscribe(globalCompact => {
                        this.ratingModels['gcRating'] = this.handleGlobalCompact(globalCompact);
                    },
                        () => { this.ratingModels['gcRating'] = this.getRatingUnavailableModel('Global Compact'); },
                        () => this.cdRef.markForCheck());
            }
            else
                this.ratingModels['gcRating'] = this.getRatingUnavailableModel('Global Compact');

            // GET ESG NEWS ARTICLES
            this.companyOverviewService.getNewsArticles(this.company.id)
                .subscribe(news => { 
                    this.companyNews = news;
                    this.cdRef.markForCheck();
                });


            this.companyProductInvolvementService.getHasActiveInvolvedAssessments(this.company.id)
                .subscribe(response => {
                    if(response.status === 200 && response.body.hasOwnProperty('hasActive')){
                        this.hasActiveInvolvedAssessments = response.body.hasActive;
                    }
                    this.cdRef.markForCheck();
                });
                
            this.cdRef.markForCheck();
            this.rootComponent.finishLoading();

            //trigger company subscriptions only if company is not coverage
            if (this.company.isCoverageEntity)
                this.companyService.company = this.companyService.companySubject.filter(x => x.isCoverageEntity == false);
        });
    }

    ngOnDestroy() {
        this.sub.unsubscribe();
    }

    private handleRiskRating(riskRating) {
        const isCore = this.company.coreRiskResearchState === ResearchState.ResearchAvailable;
        const riskRatingAssessment = riskRating.assessment;
        return new RatingOverviewModel('ESG Risk Rating', riskRating.riskRating, 100,
            `${riskRatingAssessment} Risk`, null, !isCore, isCore,
            this.companyService.getRiskRatingDownloadData(this.company)
        );
    }

    private handleEsgRating(rating) {
        return new RatingOverviewModel(
            'ESG Rating', rating.overall.score, 100,
            rating.overall.esgPosition.name, null, false,
            this.company.comprehensiveEsgResearchState !== ResearchState.ResearchAvailable,
            this.companyService.getEsgDownloadData(this.company)
        );
    }

    private handleControversy(controversies) {
        let maxControversy = -1;
        let maxSeverity = '';
        let ratingAssessment = null;

        // get max controversy
        controversies.forEach(controversy => {
            if (controversy.answerCategory > maxControversy) {
                maxControversy = controversy.answerCategory;
                maxSeverity = controversy.eventSeverity;
            }
        });

        // get rating assessment
        if (maxControversy >= 0) {
            ratingAssessment = maxControversy === 0
                ? 'No Evidence of Controversies'
                : `Category ${maxControversy} - ${maxSeverity}`;
        }

        // set icon
        const icon = `icon-cat${maxControversy}.svg`;

        return new RatingOverviewModel('Controversies', null, null, ratingAssessment, icon,
            false, false, this.companyService.getControversyDownloadData(this.company)
        );
    }

    private handleCorporateGovernance(rating) {
        return new RatingOverviewModel('Corporate Governance', rating.score, 100, AssessmentList[rating.assesment],
            undefined, false, false, this.companyService.getGovernanceDownloadData(this.company));
    }

    private getSPRating() {
        const hasSP = this.company.hasSustainableProductIndicators;
        const icon = hasSP ? 'icon-evidence.svg' : 'icon-no-evidence.svg';
        const assessment = hasSP ? 'Evidence of Involvement' : 'No Evidence of Involvement';

        //NO Download Data at this time - TODO uncomment when a pdf is created;
        //let downloadData: CompanyReportDownloadModel;
        //if (hasSP) {
            // set download report data
            //downloadData = this.companyService.getSustainableProductsDownloadData(this.company);
        //}

        return new RatingOverviewModel('Sustainable Products', null, null, assessment, icon, false, false, null);
    }

    private getPIRating() {
        const hasPI = this.company.hasProductInvolvementIndicators;
        const icon = hasPI ? 'icon-evidence.svg' : 'icon-no-evidence.svg';
        const assessment = hasPI ? 'Evidence of Involvement' : 'No Evidence of Involvement';
        let downloadData: CompanyReportDownloadModel;

        if (hasPI) {
            // set download report data
            downloadData = this.companyService.getProductInvolvementDownloadData(this.company);
        }

        return new RatingOverviewModel('Product Involvement', null, null, assessment, icon, false, false, downloadData);
    }

    private handleGlobalCompact(globalCompact) {
        if (!this.productPermissions.globalcompact) {
            return this.getRatingUnavailableModel('Global Compact');
        }

        const currentRating = globalCompact != null ? globalCompact.overallCompanyAssessment : 0;
        const ratings = [
            { icon: 'icon-compliant.svg', assesment: 'Compliant' },
            { icon: 'icon-watchlist.svg', assesment: 'Watchlist' },
            { icon: 'icon-not-compliant.svg', assesment: 'Non-Compliant' }
        ];

        return new RatingOverviewModel('Global Compact', null, null, ratings[currentRating].assesment, ratings[currentRating].icon);
    }

    private getRatingUnavailableModel(ratingName: string) {
        return new RatingOverviewModel(ratingName);
    }

    private getRoute(researchType) {
        return ['/', 'research', 'company', this.company.companyNameUrlFriendly, researchType];
    }
}
